-- Spawns a monster at a containment cell, gives a player control of it, tps their body to it and kills it too (free meal)
function spawnCharacterMonster (character, species, client, pos, delete)

	local characterReturn
	
	-- Spawn monster at containment cell
	Entity.Spawner.AddCharacterToSpawnQueue(species, pos, function (characterMonster)
		-- Give player control of their monster
		if client ~= nil then client.SetClientCharacter(characterMonster) end
		-- Teleport and kill their human bodies
		character.Kill(CauseOfDeathType.Unknown)
		character.TeleportTo(pos)
		-- Set return character
		characterReturn = characterMonster
	end)
	
	-- Delete old character
	if delete then Entity.Spawner.AddEntityToRemoveQueue(character) end
	
	return characterReturn

end

-- General code for when respawning a player as militant
function spawnPlayerMilitant (client, team, data)
	if (data ~= nil) and data['old'] then
		spawnPlayerMilitant_OLD(client, team)
	else
		spawnPlayerMilitant_NEW(client, team)
	end
	if team == 'JET' then
		FG.playerRole[client.Name] = 'jet'
		messageClient(client, 'info', '朱庇特精英部队，简称JET — T阵营的武装成员，装备了重武器、药物、护甲和高级ID卡。帮助D级人员逃离设施并杀死怪物以及所有效力于Nex制药公司的成员。')
		if (data == nil) or (not data['free']) then
			FG.terroristTickets = FG.terroristTickets - 1
		end
	elseif team == 'MERCS' then
		FG.playerRole[client.Name] = 'mercs'
		messageClient(client, 'info', '机动紧急救援作战小队，简称MERCS — Nex制药公司下的私人军事组织，装备了重武器、药物、护甲和高级ID卡。与警卫一起帮助工作人员逃离设施，并消灭D级人员、朱庇特精英部队（JET）、怪物。')
		if (data == nil) or (not data['free']) then
			FG.nexpharmaTickets = FG.nexpharmaTickets - 1
		end
	end
end

-- Spawns a human who is a militant and sets it to the client's character, distinct from SpawnPlayerMilitant_OLD
function spawnPlayerMilitant_NEW (client, team)
	if (client.Character ~= nil) and not client.Character.IsDead then
		client.Character.Kill(CauseOfDeathType.Unknown)
		client.Character.TeleportTo(findRandomWaypointByJob(team).WorldPosition)
	end
	local character
	if team == 'JET' then
		character = spawnHuman(client, 'jet', findRandomWaypointByJob('jet').WorldPosition)
		client.Character.SetOriginalTeam(CharacterTeamType.Team2)
		client.Character.UpdateTeam()
	elseif team == 'MERCS' then
		character = spawnHuman(client, 'mercs', findRandomWaypointByJob('mercs').WorldPosition)
		client.Character.SetOriginalTeam(CharacterTeamType.Team1)
		client.Character.UpdateTeam()
	end
	--[[
	Timer.Wait(function ()
		local idcard = character.Inventory.GetItemAt(0)
		idcard.GetComponentString('IdCard').TeamID = CharacterTeamType.Team1
		local property = idcard.SerializableProperties[Identifier(newProperty)]
		Networking.CreateEntityEvent(idcard, Item.ChangePropertyEventData(property, idcard))
	end, 1*1000)
	--]]
end

-- Removes the items of respawnees, gives them their proper loadout (be it JET or MERCS) and teleports them to their spawn area
function spawnPlayerMilitant_OLD (client, team)
	local character = client.Character
	-- Guard clause
	if character == nil or character.SpeciesName ~= 'human' or character.IsDead then return end
	
	-- Remove player items
	Timer.Wait(function ()
		for item in character.Inventory.AllItems do
			Entity.Spawner.AddEntityToRemoveQueue(item)
		end
	end, 250)
	-- Team Specific Actions
	if team == 'JET' then
		-- Give items
		local itemCount = 1
		for item in FG.terroristLoadout do
			Timer.Wait(function ()
				for n=1,item[2] do
					giveItemCharacter(character, item[1], 1, item[3])
				end
			end, itemCount*20+500)
			itemCount = itemCount + 1
		end
		-- Teleport player into battlefield
		character.TeleportTo(findRandomWaypointByJob('jet').WorldPosition)
	elseif team == 'MERCS' then
		-- Give items
		local itemCount = 1
		for item in FG.nexpharmaLoadout do
			Timer.Wait(function ()
				for n=1,item[2] do
					giveItemCharacter(character, item[1], 1, item[3])
				end
			end, itemCount*20+500)
			itemCount = itemCount + 1
		end
		-- Teleport player into battlefield
		character.TeleportTo(findRandomWaypointByJob('mercs').WorldPosition)
	end

	return true
end

-- Execute when players job item are given - be it a respawn wave, or the start of the match
Hook.Add("character.giveJobItems", "monsterAndRespawns", function (character)
	-- Find client
	local client = findClientByCharacter(character)
	-- Set up TeamID for player
	if isCharacterTerrorist(character) then
		character.SetOriginalTeam(CharacterTeamType.Team2)
		character.UpdateTeam()
	elseif isCharacterNexpharma(character) then
		character.SetOriginalTeam(CharacterTeamType.Team1)
		character.UpdateTeam()
	elseif (client ~= nil) and (FG.monsterPlayers[client.Name] ~= nil) then
		character.SetOriginalTeam(0)
		character.UpdateTeam()
	end
	-- Spawn JET and MERCS card via LUA due to bug
	if character.HasJob('jet') then
		Timer.Wait(function ()
			giveItemCharacter(character, 'idcardjet', 1, 0)
		end, 1*1000)
	end
	if character.HasJob('mercs') then
		Timer.Wait(function ()
			giveItemCharacter(character, 'idcardmercs', 1, 0)
		end, 1*1000)
	end
	
	-- Guard clause
	if client == nil then return end
	
	-- Spawn character monster
	if (character.Submarine ~= nil) and (character.Submarine.Info.Name == Submarine.MainSub.Info.Name) then
		-- Get monster spawnpoint
		local jobs = {}
		if FG.settings.monsterSpawn == 'default' then
			jobs = {'mutatedmantisjob', 'mutatedcrawlerjob'}
		elseif FG.settings.monsterSpawn == 'staff' then
			jobs = {'researcher', 'repairmen'}
		end
		local spawnPosition = findRandomWaypointByJob(jobs[math.random(#jobs)]).WorldPosition
		local monster = 'random'
		-- Player monster spawning
		if FG.monsterPlayers[client.Name] ~= nil then
			-- If monster is random then pick a random valid one
			monster = FG.monsterPlayers[client.Name]
			if monster == 'random' then
				if FG.settings.gamemode == 'default' then
					if math.random(2) == 1 then
						monster = 'mutatedmantis'
					else
						monster = 'mutatedcrawler'
					end
				elseif FG.settings.gamemode == 'husk' then
					monster = 'husk'
				elseif FG.settings.gamemode == 'greenskin' then
					monster = 'greenskin'
				end
			end
			-- Actual spawning
			if monster == 'mutatedmantis' then
				spawnCharacterMonster(character, 'mantisadmin', client, spawnPosition)
				
				messageClient(client, 'info', '你是变异螳螂！一只移动不便、虚弱无力但生命力极强的怪物。与剩下的怪物杀死所有人类！你可以啃食尸体，访问普通的权限门、驾驶电车和开启本地语音。')
			elseif monster == 'mutatedcrawler' then
				spawnCharacterMonster(character, 'crawleradmin', client, spawnPosition)
				
				messageClient(client, 'info', '你是变异藻爬！一只快速、蛮横且生命力较强的怪物。与剩下的怪物杀死所有人类！你可以啃食尸体，访问普通的权限门、驾驶电车和开启本地语音。')
			elseif monster == 'greenskin' then
				local isTroll = math.random(100) <= FG.settings.initialTrollPercentage
				local name = nil
				if client ~= nil then
					name = client.Name
				end
				spawnHumangoblin(client, spawnPosition, name, isTroll)
				Entity.Spawner.AddEntityToRemoveQueue(character)
				
				messageClient('你是一只绿皮怪物！一种灵活的两栖生物，喜欢和猎物玩游戏。被戴上面具的活人会变成哥布林。躲在哥布林箱中可以回复生命。')
			end
		end
	end

	-- Executed on match start to spawn in the monsters
	if (character.Submarine ~= nil) and (character.Submarine.Info.Name == Submarine.MainSub.Info.Name) then
		if isCharacterStaff(character) then
			messageClient(client, 'info', '你是一名任职于Nex制药公司的员工，身上携带着少量物资及低权限ID卡。与剩下的工作人员一起在警卫和机动紧急救援战队小队（MERCS）的帮助下逃离设施。')
		elseif character.HasJob('enforcerguard') then
			messageClient(client, 'info', '你是Nex制药公司的武装成员，身上有一张普通的警卫ID卡和配备了一把随身携带的武器。与剩下的警卫和机动紧急救援战队小队（MERCS）合作并铲除D级人员、朱庇特精英部队（JET）和怪物，同时帮助工作人员逃离设施。')
		elseif character.HasJob('eliteguard') then
			messageClient(client, 'info', '你是Nex制药公司的武装成员，身上有一张普通的警卫ID卡和配备了一把随身携带的武器。与剩下的警卫和机动紧急救援战队小队（MERCS）合作并铲除D级人员、朱庇特精英部队（JET）和怪物，同时帮助工作人员逃离设施。')
		elseif character.HasJob('mercs') then
			messageClient(client, 'info', '机动紧急救援作战小队，简称MERCS — Nex制药公司下的私人军事组织，装备了重武器、药物、护甲和高级ID卡。与警卫一起帮助工作人员逃离设施，并消灭D级人员、朱庇特精英部队（JET）、怪物。')
		elseif character.HasJob('inmate') then
			messageClient(client, 'info', '你是T阵营的文职成员，被Nex制药公司编码为D级人员，身上几乎没有任何东西。与剩下的D级人员和朱庇特精英部队（JET）合作并逃离这块悲惨的地方。')
		elseif character.HasJob('jet') then
			messageClient(client, 'info', '朱庇特精英部队，简称JET — T阵营的武装成员，装备了重武器、药物、护甲和高级ID卡。帮助D级人员逃离设施并杀死怪物以及所有效力于Nex制药公司的成员。')
		end
	end
	
	--[[
	-- Executed at respawn waves to equip and teleport the JET and MERCS
	elseif (character.Submarine ~= nil) and (character.Submarine.Info.Name == 'FG Respawn') then
		-- Inmate and Monsters respawn as JET
		if isCharacterTerrorist(character) then
			if FG.terroristTickets >= 1 then
				spawnPlayerMilitant(client, 'JET', {old = true})
			else
				messageAllClients('text-game', 'T阵营已消耗了所有的入场券 — 无法进行重生！')
				character.Kill(CauseOfDeathType.Unknown)
			end
			
		-- Guards and Staff respawn as MERCS
		elseif isCharacterNexpharma(character) then
			if FG.nexpharmaTickets >= 1 then
				spawnPlayerMilitant(client, 'MERCS', {old = true})
			else
				messageAllClients('text-game', 'Nex制药公司已消耗了所有的入场券 — 无法进行重生！')
				character.Kill(CauseOfDeathType.Unknown)
			end
		end
	end
	--]]

    return true
end)

FG.loadedFiles['spawning'] = true